The current builtin mods:
-Pipliz/BlockNPCs
--Uses API's provided by Pipliz/APIProvider to define the furnace, grinder, mint, oven, quiver, shop and workbench.
-Pipliz/APIProvider
--Provides base classes/interfaces/managers for handling jobs definition
--Provides a basic recipe manager
--Provides a researchable manager/loader
-Pipliz/BaseResearch
--Provides the base game researchables
-Pipliz/WorldConverter
--When enabled provides an interface on the server that allows moving a worlds' region files from one itemtypetable to another
-Pipliz/colonyserverwrapper/colonyserverwrapperdll
--When the game is start with +logto {port}, this mod will try and connect the logging output / chat input to a tcp socket on that port on the local host.

To get an idea of how to receive callbacks etc, take a look at the included mod sources.
For mod development I'd recommend the debug and/or development branches of the game, as those are build as unity development builds.
This should also allow connecting the unity profiler after installing unity, to log/check performance much more accurately than the included graphs. 




These callbacks are called in order of placement here:

void OnAssemblyLoaded (string p)
Called directly upon discovering a method with this attribute; passes the assemblies path as a parameter. Can't use providesfor/dependson here.
Builtin callback uses:
  pipliz.blocknpcs.assemblyload
    Calculates the blocknpc mod gamedata directory path
  pipliz.colonyserverwrapper.load
    Checks the commandline arguments for "+logto {port}", and if found, tries to connect to said port via tcp

void AfterModsLoaded (List<ModLoader.ModAssembly> list)
Called after all mods are loaded, list is the list of loaded assemblies. Useful for using reflection to link up things
Builtin callback uses:
  pipliz.apiprovider.parsemods
    Parses loaded assemblies looking for [AutoLoadedResearchable] classes, adds these to the Pipliz.APIProvider.Science.ResearchableManager.

void AfterStartup ()
Basically at the end of AfterModsLoaded. Possibly deprecated soon.
Builtin callback uses:
  pipliz.server.ai.aimanager.startthread
    Starts AI precalculation thread

void AfterSelectedWorld ()
First callback after the world to load has been determined.
  pipliz.server.loadtexturemappingfile
    Parses texture mapping file
  pipliz.server.registertexturemappingtextures
    DependsOn pipliz.server.loadtexturemappingfile
    Actually starts loading the texture files into the filetable
    So removing/changing texture mappings (ItemTypesServer.TextureMappings) should be done inbetween this and the DependsOn
  pipliz.server.registernpctextures
    Registers the hardcoded npc texture paths to load into the FileTable cache
  pipliz.server.registerwatertextures
    Registers the hardcoded water texture paths to load into the FileTable cache
  pipliz.server.registeraudiofiles
    Loads the gamedata/audio/audioFiles.json file.
    To add custom audio description json's: Make a callback inbetween registeraudiofiles and loadaudiofiles, where you add the jsonnode to the array jsonnode to ItemTypesServer.AudioFilesJSON
  pipliz.server.loadaudiofiles
    DependsOn pipliz.server.registeraudiofiles
    Registers the .ogg's from ItemTypesServer.AudioFilesJSON and creates the byte[] package to send to users
  pipliz.server.localization.startload
    Starts loading the json files from disk

void AfterAddingBaseTypes (Dictionairy<string, ItemTypesServer.ItemTypeRaw> dict)
Allows altering {dict}, to add/remove types
  pipliz.blocknpcs.addlittypes
    Adds the lit rotatable types like furnace/oven/bloomery/fineryforge/kiln through code.
    They're not in types.json due to the length and repetitiveness of the child types (2x4 + 2, 2 parent types + 2 for lit/unlit * 4 for rotations)

void AfterItemTypesDefined ()
Do things that require all itemtypes to be defined here. Loading recipes etc.
Builtin callback uses:
  pipliz.server.registercallbacks
    Registers base game ItemTypesServer callbacks
  pipliz.server.terraingenerator.setdefault
    Sets the default terrain generator
  pipliz.server.blackandwhitelistingreload
    Loads the whitelist & blacklist files
  pipliz.server.loadpermissions
    Loads the permissions files
  pipliz.server.loadtimecycle
    Loads the time into the timecycle class
  pipliz.server.loadupdatableblocks
    Loads the various updatable blocks (wheat, saplings, flax)
  pipliz.server.loadwater
    Loads the tracked water blocks (for updates)


  pipliz.blocknpcs.registerjobs
    [ProvidesFor("pipliz.apiprovider.jobs.resolvetypes")] -> registers jobs to the apiprovider to resolve
    Registers npc recipes to the APIPRovider RecipeManager
  pipliz.server.loadnpctypes
	[ProvidesFor("pipliz.server.loadnpcs")] -> npc's need the npc types
    Loads NPCTypes from "gamedata/npctypes.json"
  pipliz.server.registermonstertextures
    [DependsOn("pipliz.server.loadnpctypes")]
	Queues up the monster textures from npc settings to load in the filetable
  pipliz.apiprovider.jobs.resolvetypes
    [DependsOn("pipliz.server.loadnpctypes")] -> Wait for base game to add npc types first, to allow overriding
	[ProvidesFor("pipliz.apiprovider.registerrecipes")] -> Checks the job types for recipes, adds those to a list for registerrecipes
	Inserts the registered jobs' npctypes into the game
  pipliz.apiprovider.registerrecipes
    [ProvidesFor("pipliz.server.loadresearchables")]
    Inserts the registered jobs' crafting recipes into the game
  pipliz.server.recipeplayerload
    [ProvidesFor("pipliz.server.loadresearchables")] -> researchables may try unlocking these recipes
    Loads recipes from "gamedata/crafting.json"
  pipliz.server.loadresearchables
    [ProvidesFor("pipliz.server.loadplayers")] -> as player savegames contain research progress (which references researchables)
    Loads the researchables
  pipliz.server.loadsortorder
    [ProvidesFor("pipliz.server.loadplayers")] -> load players loads the stockpile, which needs this sorting
	Loads the itemtypes sort order (into ItemTypesServer.ItemSortOrder)
  pipliz.server.loadplayers
    Loads the player save files (stockpile, inventory, position)
  pipliz.server.loadbanners
    [DependsOn("pipliz.server.loadplayers")] -> banners store per player
    Loads banners
  pipliz.server.loadnpcs
    [DependsOn("pipliz.server.loadbanners")] -> laborers are stored per banner
    Loads the saved npc's
  pipliz.server.loadberryareajobs
  pipliz.server.loadwheatfarmerareajobs
  pipliz.server.loadflaxfarmerareajobs
  pipliz.server.loadforesterareajobs
  pipliz.server.loadminerareajobs
  pipliz.server.loadbedblocks
  pipliz.server.loadstockpileblocks
    For all of these:
    [DependsOn("pipliz.server.loadnpcs")] -> they deal with npc's or need banners/players loaded
    Load various tracked blocks

void OnAddResearchables ()
Place to add researchables to Server.Science.ScienceManager
Builtin callback uses:
  pipliz.apiprovider.registerresearchables
    Registers the researchables from Pipliz.APIProvider.Science.ResearchableManager to the Server.Science.ScienceManager.

void AfterWorldLoad ()
After all misc data is loaded (structures, npc's, player data, lots)
Builtin callback uses:
  pipliz.apiprovider.jobs.registercallbacks
    Registers the OnAdd/OnRemove callbacks from the blockjobs added through BlockJobManagerTracker.Register
  pipliz.apiprovider.jobs.load
    Loads the registered blockjobs from the savegame, if any exist
  pipliz.server.monsterspawner.register
    Registers the default monster spawner to MonsterTracker.MonsterSpawner
  pipliz.server.monsterspawner.fetchnpctypes
    Fetches the zombie types (aa -> cc)
  pipliz.server.ai.aimanager.defaultpathfinder
    Sets the Server.AI.AIManager.PathFinder instances to the DefaultPathFinder.

  pipliz.server.localization.waitforloading
    Waits to ensure the files in Server.Localization.LoadedTranslation are fully loaded
  pipliz.server.localization.convert
    DependsOn pipliz.server.localization.waitforloading
    Converts the json nodes into byte[] packages for networking.
    To add/change/remove localization, edit the desired JSONNode in Server.Localization.Localization.LoadedTranslation in a callback that has the following attributes:
      [ModLoader.ModCallbackDependsOn("pipliz.server.localization.waitforloading")]
      [ModLoader.ModCallbackProvidesFor("pipliz.server.localization.convert")]

void AfterNetworkSetup ()
After the NetworkWrapper class is loaded, ready to send data. Can take a few seconds for steam servers - it's after port forwarding etc is done on another thread.




These callbacks are done at various times:

void OnUpdateStart ()
Start of Unity's Update loop, before anything is called (except for quitting mechanisms).

void OnUpdate ()
Just after OnUpdateStart, after the ThreadManager did main thread delegates. Probably the place to put the bulk of per-frame-updates.
Builtin callback uses:
  pipliz.server.senddirtyscience
    Sends updates from changed science managers to their owners on an interval
  pipliz.colonyserverwrapper.process
    If +logto was specified as launch argument, this will receive the input from said port

void OnUpdateEnd ()
Just before the end of the update loop, after OnUpdate (after all relevant gamecode)

void OnGUI ()
Unity's legacy GUI loop - use UnityEngine.GUI calls here to implement some basic interface things (on the server)

void FixedUpdate ()
Unity's FixedUpdate loop

void LateUpdate ()
Unity's LateUpdate loop (comes after Update and some unity internal things)

void OnApplicationFocus (bool b)
Unity's OnApplicationFocus method.

void OnApplicationPause (bool b)
Unity's OnApplicationPause method (probably unused, as the game does not have proper support for pausing, but hey here is an entry)

void OnPlayerConnectedEarly (Player p)
Player {p} connected to the server. Very early call, player will probably ignore most messages here.
Builtin callback uses:
  pipliz.server.resetsciencedeltaupdates
    Resets ScienceManagerPlayer to send initial progress again

void OnPlayerConnectedLate (Player p)
Player {p} connected to the server. Messages sent here will be received after the client is done loading. Allows for chat messages.
Builtin callback uses:
  pipliz.server.queueinitialsend
    Queues a send to the player, to set initial science state
  pipliz.server.sendnpctypes
    Sends the npctypes packet
  pipliz.server.sendaudiomapping
    Sends the audio description json (ItemTypes.AudioFilesJSON)
  pipliz.server.meshedobjects.sendtable
    Sends the meshed objects table
  pipliz.server.terraingenerator.startsendingbiomedata
    Starts sending biome data to the player (for ambient audio mainly)
    Calls ITerrainGenerator.StartSendingBiomeData on the active terrain generator.
  pipliz.server.sendsetflight
    Sends whether or not /setflight true was active

void OnPlayerDisconnected (Player p)
Player {p} was disconnected.

void OnPlayerMoved (Player p)
Player {p} sent an updated position. Called approx 6 times per second per player. New position/rotation is set in {p}.

bool OnTryChangeBlockUser (ModLoader.OnTryChangeBlockUserData d)
Player {d.requestedBy} requested a block change from {d.typeTillNow} to {d.typeToBuild} at {d.VoxelToChange}.
Used for building/digging by the player. The client assumes the change is okay, and renders the change immediately to reduce ping.
Returning false will send a revert-the-change message to the client.
Return whether or not to allow this change

bool OnTryChangeBlockUserRequest (ModLoader.OnTryChangeBlockUserRequestData d)
Similar to OnTryChangeBlockUser, but the client does not pre-emptively do the change, and does not expect a response.
Used for the remove special block menu (banner, miner jobs, guard jobs)
Return whether or not to allow this change

void OnLoadingPlayer (JSONNode n, Player p)
Player {p} was loaded with json file {n}.
Builtin callback uses:
  pipliz.server.loadplayerscience
    Loads any science progress from the jsonnode
  pipliz.server.loadplayerlimits
    Loads any player limits from the jsonnode
  pipliz.server.loadsetflight
    Loads whether or not /setflight true is active

void OnSavingPlayer (JSONNode n, Player p)
Player {p} is being saved into json file {n}.
Builtin callback uses:
  pipliz.server.saveplayerscience
    Saves any science progress from the player to it's file
  pipliz.server.saveplayerlimits
    Saves any player limits to it's file
  pipliz.server.savesetflight
    Saves whether or not /setflight true is active

void OnQuitEarly ()
Called upon quitting gracefully
General.Application.OnQuit @ -200, called before most other on quit actions
Builtin callback uses:
  pipliz.shared.waitforasyncquitsearly
    Waits for any async autosaving etc to complete before starting onquit events

void OnQuit ()
Called upon quitting gracefully
General.Application.OnQuit @ 0, after connected players are disconnected, various things saving at the same timepipliz.apiprovider.registerrecipes
Builtin callback uses:
  pipliz.server.ai.aimanager.quitthread
    Pokes the AI precalculation thread from sleeping so it can quit
  pipliz.server.saveberryareajobs
  pipliz.server.savewheatfarmerareajobs
  pipliz.server.saveflaxfarmerareajobs
  pipliz.server.saveforesterareajobs
  pipliz.server.saveminerareajobs
  pipliz.server.savebanners
  pipliz.server.savebedblocks
  pipliz.server.savestockpileblocks
    Save various tracked blocks
  pipliz.server.savenpc
    Saves npc's
  pipliz.server.savetimecycle
    Saves time to WorldSettings
  pipliz.server.saveupdatableblocks
    Saves the updatable blocks (wheat, flax, saplings)
  pipliz.server.savewater
    Saves the updatable water blocks

void OnQuitLate ()
Called upon quitting gracefully
General.Application.OnQuit @ 100, after most quit actions happened
  pipliz.server.saveworldsettings
    Saves the servermanager.worldsettings
  pipliz.shared.waitforasyncquits
    Waits for the General.Application start async quits to complete.
  pipliz.colonyserverwrapper.dispose
    [DependsOn("pipliz.server.saveworldsettings")] - so that logs from there are also sent
    [DependsOn("pipliz.shared.waitforasyncquits")] - ^
    Closes the log streams if they were open

void OnResearchableCompleted (Server.Science.IResearchable res)
Called upon completion of a researchable

void OnPlayerDeath (Players.Player p)
Called upon the death of player p.
Builtin callback uses:
  pipliz.server.onplayerdeath
    Sets health to 0, sends audio, clears inventory, prints death to log

void OnPlayerRespawn (Players.Player p)
Called upon the respawning of player p (player clicked the button).
Builtin callback uses:
  pipliz.server.onplayerrespawn
    Teleports player to their base, sets health to starting health, prints respawn to log

void OnItemTypeRegistered (ItemTypes.ItemType type)
Called when a resolved type is registered to ItemTypes
Builtin callback uses:
  pipliz.server.itemtypesserver
    Parses server specific things of itemtypes:
      Registers the parents of types for use with itemtype actions
      Adds icons from types to the FileTable cache
      Adds meshes from types to the FileTable cache

void OnMonsterDied (IMonster monster)
Called when a monster died

void OnMonsterHit (IMonster monster, Pipliz.Box<float> box)
box.item1 -> damage
{monster} is getting hit for {damage}. Can adjust damage. Don't store the Box<>.

void OnMonsterSpawned (IMonster monster)
Called when a monster was spawned

void OnNPCLoaded (NPC.NPCBase npc, JSONNode node)
Loaded {npc} from {node}

void OnNPCSaved (NPC.NPCBase npc, JSONNode node)
Saved {npc} into {node} - can add custom values to the node

void OnNPCRecruited (NPC.NPCBase npc)
Recruited NPC {npc} - see npc.Colony for ownership

void OnNPCDied (NPC.NPCBase npc)
{npc} died - see npc.Colony for ownership
Builtin callback uses:
  pipliz.server.refundrecruitement
    If the npc had a job, refund the recruitment item to the stockpile

void OnNPCJobChanged (TupleStruct<NPC.NPCBase, IJob, IJob> data)
data.item1 -> {npc}
data.item2 -> {old job}
data.item3 -> {new job}
{npc} has changed job from {old job} to {new job}
Builtin callback uses:
  pipliz.server.refundrecruitement
    Add {old job} recruitment item to the stockpile

void OnNPCHit (NPC.NPCBase npc, Pipliz.Box<float> box)
box.item1 -> damage
{npc} is getting hit for {damage}. Can adjust damage. Don't store the Box<>.

void OnPlayerHit (Players.Player player, Pipliz.Box<float> box)
box.item1 -> damage
{player} is getting hit for {damage}. Can adjust damage. Don't store the Box<>.

void OnPlayerClicked (Players.Player player, Pipliz.Box<Shared.PlayerClickedData> boxedData)
boxedData.item1 -> clickedData
{player} clicked, resulting in {clickedData}. Don't store the Box<>.
Check {clickedData.consumedType} if the click was already consumed by something
Check {clickedData.clickType} whether it's a left or right click
Check {clickedData.rayCastHit.rayHitType} for which data is valid.
  If it's Block, distanceToHit, voxelHit, voxelSideHit and typeHit become valid
  If it's NPC, distanceToHit and hitNPCID become valid
Builtin callback uses:
  pipliz.server.players.hitnpc
    Checks if the player hit an npc, if that's the case, cause damage to it

The following 'paragraph' callbacks are all called from the filesaver thread. Be careful with multithreading, a significant portion of the game is not threadsafe.

void OnSavedRegionToDisk ()
A region is saved to the disk. Also possibly called when quitting the game, and then it's called from a random thread pool thread (!!!)

void OnLoadedRegionFromDisk ()
A region is loaded from the disk.

void OnSavedChunkToRegion ()
A chunk is saved to the region. The chunk is locked for reading data.

void OnLoadedChunkFromRegion ()
A chunk is filled from a region in memory. The chunk is locked for writing data.

void OnAutoSaveWorld ()
Triggered every x seconds, to autosave non-block data (jobs, npc's, players)
Builtin callback uses:
  A lot. Basically all callbacks from OnQuit to do with saving are in here as well (but then with auto in their identifier)

NPC temporary values - unused by server code
Monster temporary values - unused by server code
Player Temporary values: Variables stored in player.GetTempValues() dict (if set - defaults may not be in there)

float pipliz.healthregenmax
  Limit to which health regenerates, set by health regen size research

float pipliz.healthregenspeed
  Speed at which health regenerates, set by health regen speed research 

float pipliz.healthmax
  Max health, set by health size research

int pipliz.bannersaferadius
  Monster spawn safe radius

bool pipliz.setflight
  Whether or not /setflight true is active
